// Use of this source code is governed by a BSD-style license
// that can be found in the License file.

// Author: Shuo Chen (chenshuo at chenshuo dot com)
//
// This is a public header file, it must only include public header files.

#ifndef YHAIDA_FILEUTIL_H
#define YHAIDA_FILEUTIL_H

#include "Utils.h"
#include <string>
#include <sys/types.h> // for off_t

namespace yhaida
{
    using std::string;
    namespace FileUtil
    {

        // read small file < 64KB
        class ReadSmallFile : Utils::nocapyable
        {
        public:
            ReadSmallFile(std::string filename);
            ~ReadSmallFile();

            // return errno
            template <typename String>
            int readToString(int maxSize,
                             String *content,
                             int64_t *fileSize,
                             int64_t *modifyTime,
                             int64_t *createTime);

            /// Read at maxium kBufferSize into _buf
            // return errno
            int readToBuffer(int *size);

            const char *buffer() const { return _buf; }

            static const int kBufferSize = 64 * 1024;

        private:
            int _fd;
            int _err;
            char _buf[kBufferSize];
        };

        // read the file content, returns errno if error happens.
        template <typename String>
        int readFile(std::string filename,
                     int maxSize,
                     String *content,
                     int64_t *fileSize = NULL,
                     int64_t *modifyTime = NULL,
                     int64_t *createTime = NULL)
        {
            ReadSmallFile file(filename);
            return file.readToString(maxSize, content, fileSize, modifyTime, createTime);
        }

        // not thread safe
        class AppendFile : Utils::nocapyable
        {
        public:
            explicit AppendFile(std::string filename);

            ~AppendFile();

            void append(const char *logline, size_t len);

            void flush();

            off_t writtenBytes() const { return _writtenBytes; }

        private:
            size_t write(const char *logline, size_t len);

            FILE *_fp;
            char _buffer[64 * 1024];
            off_t _writtenBytes;
        };
    } 
} 

#endif
